using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml.Linq;
using Tool;


namespace SerialPortCommunicationProject
{
    /// <summary>
    /// NewCommandWindow.xaml 的交互逻辑
    /// </summary>
    public partial class NewCommandWindow : Window
    {
        Database database = Database.GetInstance();
        private Device device;
        private string deviceName;
        public NewCommandWindow(Device device, string deviceName)
        {
            InitializeComponent();
            LoadControlsDataSource();
            this.device = device;
            TbBox_DeviceName.Text = deviceName;
            this.deviceName = deviceName;
            if (App.CurrentCommand.Name == "双击添加" || App.CurrentCommand.Name=="+")
            {
                TBox_CommandName.Text = string.Empty;
            }
            else
            {
                TBox_CommandName.Text = App.CurrentCommand.Name;
            }
            TBox_CommandCode.Text = App.CurrentCommand.Code;
        }
        Modbus modbus = new Modbus();
        FormatType type = FormatType.Ascii;

        private void LoadControlsDataSource()
        {
            //Data Source
            List<FunctionCode> functionCodes = new List<FunctionCode>
            {
                new FunctionCode(){Code="01H",Meaning="读线圈寄存器"},
                new FunctionCode(){Code="02H",Meaning="读离散输入寄存器"},
                new FunctionCode(){Code="03H",Meaning="读保持寄存器"},
                new FunctionCode(){Code="04H",Meaning="读输入寄存器"},
                new FunctionCode(){Code="05H",Meaning="写单个线圈寄存器"},
                new FunctionCode(){Code="06H",Meaning="写单个保持寄存器"},
                new FunctionCode(){Code="0fH",Meaning="写多个线圈寄存器"},
                new FunctionCode(){Code="10H",Meaning="写多个保持寄存器"},
            };

            //Data Binding
            this.CbBox_FunctionCode.ItemsSource = functionCodes;
            this.TBox_Address.SetBinding(TextBox.TextProperty, new Binding("Address") { Source = modbus });
            this.TBox_Start.SetBinding(TextBox.TextProperty, new Binding("Start") { Source = modbus });
            this.TBox_Count.SetBinding(TextBox.TextProperty, new Binding("Count") { Source = modbus });

            this.CbBox_FunctionCode.SelectedIndex = 0;
        }

        private void Bt_GenerateCommand_Click(object sender, RoutedEventArgs e)
        {
            List<byte> code=modbus.GenerateCode(this.TBox_Address.Text.Replace(" ", "").PadLeft(2,'0'), 
                this.CbBox_FunctionCode.Text.Substring(0, 2),
                this.TBox_Start.Text.Replace(" ", "").PadLeft(4,'0'),
                this.TBox_Count.Text.Replace(" ", "").PadLeft(4,'0'));
            this.TBox_CommandCode.Text = BitConverter.ToString(code.ToArray()).Replace("-", " ");
        }

        /// <summary>
        /// 点击修改指令生成帮助框的可见性
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_PullDown_Click(object sender, RoutedEventArgs e)
        {
            if (this.Panel_Helper.Visibility == Visibility.Collapsed)
            {
                this.Panel_Helper.Visibility = Visibility.Visible;
                this.Panel_Helper.Height = 160;
                this.Height += 160;
                ChangeImageSource(Btn_PullDown.Content as Image,"/Assets/arrow-up.png");

            }
            else
            {
                this.Panel_Helper.Visibility = Visibility.Collapsed;
                this.Panel_Helper.Height = 0;
                this.Height -= 160;
                ChangeImageSource(Btn_PullDown.Content as Image,"/Assets/arrow-down.png");
            }
        }
        private void ChangeImageSource(Image image,string uri)
        {
            if (image != null)
            {
                // Create the image element.
                Image simpleImage = new Image();
                simpleImage.Width = 200;
                simpleImage.Margin = new Thickness(5);

                // Create source.
                BitmapImage bi = new BitmapImage();
                // BitmapImage.UriSource must be in a BeginInit/EndInit block.
                bi.BeginInit();
                bi.UriSource = new Uri(uri, UriKind.RelativeOrAbsolute);
                bi.EndInit();
                // Set the image source.
                image.Source = bi;
            }
        }

        /// <summary>
        /// 指令代码失去焦点的事件处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TBox_CommandCode_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            if ((this.Owner as NewDeviceWindow) != null)
            {
                var owner = this.Owner as NewDeviceWindow;
                type = App.StringToFormat(owner.CbBox_Encoding.Text);
            }
            else if ((this.Owner as DeviceSelectWindow) != null)
            {
                var owner = this.Owner as DeviceSelectWindow;
                Device currentDevice = App.LstDevices[owner.lBox_Devices.SelectedIndex];
                type = App.StringToFormat(currentDevice.Encoding);
            }
            App.FormatCommandCode(this.TBox_CommandCode.Text, this.TBox_CommandCode,type);
        }

        private void AddCommand(bool isNew, bool isSaveInDatabase)
        {
            Command newCommand = new Command()
            {
                Name = TBox_CommandName.Text,
                Code = TBox_CommandCode.Text
            };
            if (isNew)
            {
                foreach(Command c in device.Commands)
                {
                    if (newCommand.Name.Equals(c.Name))
                    {
                        MessageBox.Show("指令名称重复！");
                        return;
                    }
                }
                device.Commands.Insert(device.Commands.Count-1, newCommand);

                if (isSaveInDatabase)
                {
                    database.AddCommand(newCommand.Name, device.Name, newCommand.Code);
                }
            }
            else
            {
                int index = App.CurrentDevice.Commands.IndexOf(App.CurrentCommand);
                App.CurrentDevice.Commands[index] = newCommand;
                App.CurrentCommand = newCommand;

                if (isSaveInDatabase)
                {
                    database.ModifyCommand(device.Name, newCommand.Name, newCommand.Code);
                }
            }
           
        }

        private void Btn_Save_Click(object sender, RoutedEventArgs e)
        {
            if (App.CurrentCommand.Name.Equals("+")) 
            {
                AddCommand(true, true);
            } else if(App.CurrentCommand.Name.Equals("双击添加"))
            {
                AddCommand(true, false);
            }
            else
            {
                if (device.Name.Equals("+"))
                {
                    AddCommand(false, false);
                }
                else
                {
                    AddCommand(false, true);
                }
                
            }
            this.Close();
        }

        private void Btn_Cancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void Window_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    try
                    {
                        this.DragMove();
                    }
                    finally
                    { }
                }));
            }
        }
    }
}
